<template>
  <div>
    <div style="background: #fff; padding: 20px">
      <div class="mt-1">
        <a-card>
          <BasicTable
            @register="registerTable"
            :row-selection="table.rowSelection"
            rowKey="id"
            bordered
            showTableSetting
            :useSearchForm="true"
            :showIndexColumn="table.showIndexColumn"
            :expandRowByClick="true"
          >
            <template #tableTitle>
              <div v-if="table.toolbar.length > 0 && !withTrash">
                <a-space>
                  <a-button v-for="(item, index) in table.toolbar" :key="index" :color="item.color" :type="item.type" @click="toolbar(item.key)">
                    <Icon :icon="item.icon" color="#FFFFFF" :size="item.size"></Icon>
                    {{ item.label }}
                  </a-button>
                  <div class="pt-3 pr-10"><Icon v-if="table.trash.length > 0" icon="mdi:delete-outline" color="#2979FF" size="26" @click="setWithTrash()"></Icon></div>
                </a-space>
              </div>

              <div v-if="table.trash.length > 0 && withTrash">
                <a-space>
                  <a-button v-for="(item, index) in table.trash" :key="index" :color="item.color" :type="item.type" @click="toolbar(item.key)">
                    <Icon :icon="item.icon" color="#FFFFFF" :size="item.size"></Icon>
                    {{ item.label }}
                  </a-button>
                  <div class="pt-3 pr-10"><Icon v-if="table.toolbar.length > 0" icon="mdi:undo-variant" color="#2979FF" size="26" @click="setWithTrash()"></Icon></div>
                </a-space>
              </div>
            </template>

            <template #images="{ record, column }">
              <TableImg :imgList="imageList(record[column.dataIndex])" :size="35" :simpleShow="true" :showBadge="true" />
            </template>

            <template #switch="{ record, column }">
              <a-switch
                v-model:checked="record[column.dataIndex]"
                :checkedValue="1"
                :unCheckedValue="0"
                checked-children="是"
                un-checked-children="否"
                @change="switchChange(record, column.dataIndex)"
              />
            </template>

            <template #action="{ record }">
              <a-button v-for="(item, index) in table.action" :key="index" :preIcon="item.icon" size="small" type="link" @click="toolbar(item.key, record)">
                {{ item.label }}
              </a-button>
              <span v-if="table.dropAction.length > 0">
                <a-dropdown>
                  <template #overlay>
                    <a-menu>
                      <a-menu-item v-for="(item, index) in table.dropAction" :key="index" @click="toolbar(item.key, record)">
                        <Icon :icon="item.icon" color="#2979FF"></Icon>
                        <span class="text-blue-600">{{ item.label }}</span>
                      </a-menu-item>
                    </a-menu>
                  </template>
                  <a-button type="link" size="small">....</a-button>
                </a-dropdown>
              </span>
            </template>

            <template #toolbar>
              <div v-if="select.index.length > 0" @click="clearSection"><a-badge :count="select.index.length" /></div>
              <Icon icon="fluent:book-question-mark-24-regular" size="22" @click="showDocument"></Icon>
            </template>
          </BasicTable>
        </a-card>
      </div>
    </div>

    <BasicModal v-model:visible="form.visible" :forceRender="true" :title="form.title" :width="850" :loading="form.loading" @ok="saveData">
      <BasicForm @register="registerForm" :showActionButtonGroup="false">
        <template #InputRange="{ schema, model, field, values }">
          <div>
            <a-input v-model:value="model[schema.componentProps.items[0]]" style="width: 130px; text-align: left" placeholder="最小值" />
            ~
            <a-input v-model:value="model[schema.componentProps.items[1]]" style="width: 130px; text-align: left; border-left: 1" placeholder="最大值" />
            <span class="ml-2">{{ schema.componentProps.items[2] }}</span>
          </div>
        </template>
        <template #editor="{ schema, model, field, values }">
          <div><Tinymce v-model="model[field]" width="100%" /></div>
        </template>
      </BasicForm>
    </BasicModal>

    <a-drawer title="说明文档" placement="right" :closable="false" :visible="document.show" @close="document.show = false" width="25%">
      <div>
        <p>{{ document.content }}</p>
      </div>
    </a-drawer>
  </div>
</template>

<script lang="ts">
import { BasicTable, TableImg, useTable } from '/@/components/Table';
import { BasicModal } from '/@/components/Modal';
import { BasicForm, useForm } from '/@/components/Form';
import { Icon } from '/@/components/Icon';
import { Tinymce } from '/@/components/Tinymce/index';
import { ref, reactive, toRefs, watch, defineComponent } from 'vue';
import { message } from 'ant-design-vue';
import { Modal } from 'ant-design-vue';

import { Restful } from '/@/vpage';
import { getFormDefaultValue } from '/@/vpage/func/';

export default defineComponent({
  name: 'dataView',
  components: {
    BasicTable,
    TableImg,
    BasicModal,
    BasicForm,
    Icon,
    Tinymce
  },
  data() {
    return {};
  },
  props: {
    page: {
      type: Object,
      default() {
        return {};
      }
    }
  },
  setup(props, context) {
    let page = props.page;

    // 设置多选框
    const rowSelection = {
      onChange: data => {
        state.select.index = data;
      },
      onSelect: data => {},
      onSelectAll: data => {}
    };
    // 解构数组
    const [registerTable, tableMethods] = useTable(page.useTable());
    // 解构对象 表格方法，这里解构的是在当前页面使用
    let { reload, clearSelectedRowKeys, updateTableDataRecord } = tableMethods;

    // 表单项设置
    const schemas = page.useForm();

    // 解构表单
    const [registerForm, formMethods] = useForm({
      labelWidth: 80,
      layout: 'horizontal',
      schemas,
      actionColOptions: {
        span: 24
      }
    });
    let { getFieldsValue, setFieldsValue, resetFields } = formMethods;

    const state = reactive({
      form: {
        title: '新增',
        visible: false,
        loading: false,
        loadingTip: '正在提交中',
        schemas: [],
        id: 0
      },
      table: {
        toolbar: page.table.toolbar,
        trash: page.table.trash,
        action: page.table.action,
        dropAction: page.table.dropAction,
        showIndexColumn: page.table.showIndexColumn === true ? true : false,
        rowSelection: page.table.rowSelection === true ? rowSelection : null
      },
      withTrash: false,
      select: {
        // 选中的
        index: [],
        // 单行删除的
        id: 0
      },
      // 是否已经警告
      warning: false,
      document: {
        show: false,
        content: '当前页面暂无说明'
      }
    });

    const imageList = resp => {
      let type = typeof resp;
      if (Array.isArray(resp)) {
        return resp;
      } else if (type === 'string') {
        return [resp];
      } else {
        return [];
      }
    };

    /**
     * value 等于 -1 表示加载回收站的数据
     */
    const setWithTrash = () => {
      state.withTrash = !state.withTrash;
      page.withTrash = state.withTrash;
      clearSelectedRowKeys();
      reload();
    };

    const resetForm = (close: boolean = true) => {
      resetFields();
      state.form.visible = close === true ? false : true;
    };

    // 打包后保存按钮，会请求两次，排查不出来原因，就使用变量标记
    let saveFlag = true;
    const editRow = async (key, data) => {
      // 回收站模式下不能使用编辑模式
      if (state.withTrash) {
        message.warning('回收站模式下不能使用编辑功能');
        return false;
      }

      // 回填表单
      const resetFormValue = record => {
        let fields = getFieldsValue();
        for (let item of schemas) {
          fields[item.field] = getFormDefaultValue(item, record[item.field]);
        }
        setFieldsValue(fields);
      };

      resetFields();
      state.form.visible = true;
      saveFlag = true;

      if (key == 'edit') {
        state.form.title = '编辑';
        const record = await Restful.get(page.name, data.id);
        state.form.id = data.id;
        resetFormValue(record);
      } else {
        state.form.id = 0;
        state.form.title = '新增';
        if (data) {
          setFieldsValue(data);
        }
      }
    };

    const saveData = async () => {
      let value = getFieldsValue();
      if (value.region && Array.isArray(value.region)) {
        // 处理成字符串，是为了保存的时候验证长度
        value.province_id = value.region[0] + '';
        value.city_id = value.region[1] + '';
        value.area_id = value.region[2] + '';
      }
      if (saveFlag === false) {
        saveFlag = true;
        return saveFlag;
      }
      saveFlag = false;

      let result = null;
      let msg = '数据列更新成功';
      if (state.form.id) {
        value.id = state.form.id;
        result = await Restful.put(page.name, value);
      } else {
        msg = '新增数据列成功';
        result = await Restful.post(page.name, value);
      }

      saveFlag = true;

      if (result === true || result > 0) {
        message.success(msg);
        resetForm();
        if (state.form.id) {
          updateTableDataRecord(state.form.id, getFieldsValue());
        } else {
          reload();
        }
      } else {
        console.log(result, 'result');
      }
    };

    const removeRow = async () => {
      if (state.select.index.length === 0 && state.select.id === 0) {
        message.warning('请选择需要删除的行');
        return false;
      }

      if (state.warning === false) {
        Modal.confirm({
          title: '高危操作',
          content: '请您再次确认是否继续?',
          onOk() {
            state.warning = true;
            removeRow();
          }
        });
        return false;
      }
      state.warning = false;

      let ids = [];
      ids = ids.concat(state.select.index);
      if (state.select.id > 0) {
        ids.push(state.select.id);
      }

      const index = message.loading({ content: '正在提交....请稍后...', duration: 0 });

      // 判断是移动到回收站还是测试删除
      let result;
      // 处于回收站模式下，执行删除操作
      if (state.withTrash) {
        result = await Restful.clean(page.name, ids);
      } else {
        // 移动到回收站
        result = await Restful.trash(page.name, ids);
      }

      if (typeof result === 'number') {
        message.success(result + ' 行数据删除完成');
        setTimeout(index, 1000);
        reload();
        state.select.index = [];
        state.select.id = [];
      } else {
        index();
      }
    };

    const recoverRow = async () => {
      if (state.select.index.length === 0) {
        message.warning('请选择需要恢复的行');
        return false;
      }

      let ids = state.select.index;

      const index = message.loading({ content: '正在提交....请稍后...', duration: 0 });

      // 判断是移动到回收站还是测试删除
      let result = await Restful.recovery(page.name, ids);

      if (typeof result === 'number') {
        message.success(result + ' 数据行恢复完成');
        setTimeout(index, 1000);
        reload();
        state.select.index = [];
        state.select.id = [];
      } else {
        index();
      }
    };

    const toolbar = (key, data) => {
      console.log('操作类型', key);
      let action = (_key, _data) => {
        if (_key === 'plus') {
          editRow('plus', _data);
        } else if (_key === 'edit') {
          editRow('edit', _data);
        } else if (_key === 'remove' || _key === 'clean') {
          if (data && data.id) {
            state.select.id = parseInt(data.id);
          }
          removeRow();
        } else if (_key === 'download') {
          message.error('功能待开发');
        } else if (_key === 'recovery') {
          recoverRow();
        }
      };

      context.emit('report', {
        key: key,
        data: data,
        callback: resp => {
          if (typeof resp === 'object') {
            let rk = resp.key;
            let rd = resp.data;
            if (rk) {
              key = rk;
            }
            if (rd) {
              data = rd;
            }
          }
          action(key, data);
        }
      });
      return;
    };

    const switchChange = (data, key) => {
      let id = parseInt(data.id);
      if (id > 0) {
        Restful.patch(page.name, { id: id, key: key, value: data[key] }).then(resp => {
          if (resp !== true) {
            data.status = !data.status;
          } else {
            message.success('更新成功');
          }
        });
      }
    };

    const showDocument = () => {
      state.document.show = true;
    };

    const clearSection = () => {
      Modal.confirm({
        title: '友情提示',
        content: '请您再次确认是否移除已选项?',
        centered: false,
        onOk: function() {
          clearSelectedRowKeys();
        }
      });
    };

    context.emit('report', {
      methods: {
        table: tableMethods,
        form: formMethods
      }
    });

    return {
      ...toRefs(state),
      registerTable,
      registerForm,
      schemas,
      showDocument,
      rowSelection,
      clearSection,
      toolbar,
      setWithTrash,
      saveData,
      switchChange,
      imageList
    };
  }
});
</script>

<style>
.dialog-container {
  height: 400px;
}

.dialog-footer {
  text-align: center;
}

.confirm {
  margin: 15px 0;
}

.paginate {
  padding: 10px 0;
  text-align: right;
}
</style>
